﻿using Engine.Graphics;
using Engine.Shape;
using System;
using System.Windows.Forms;

namespace ModelViewer.TabsForModelviewerControls
{
    public partial class ShapeModifer : UserControl, IRenderableObject
    {
        #region Private Fields

        private Engine.Engine engine;

        private ModelViewerForm modelViewer;

        /// <summary>
        /// Shape which rendered the selected borders without z-Buffer and in Red.
        /// </summary>
        private Shapes renderShape;

        private Shapes shape;

        #endregion Private Fields

        #region Public Constructors

        public ShapeModifer()
        {
            InitializeComponent();
        }

        #endregion Public Constructors

        #region Public Methods

        public void InitializeEngine(Engine.Engine engine, ModelViewer.ModelViewerForm modelViewerForm)
        {
            this.modelViewer = modelViewerForm;
            this.engine = engine;
            this.renderShape = new Shapes(this.engine.Device);
            this.engine.Grafic.AddRenderableObjects(this, 1000);
        }

        public void OnNewShape(object sender, EventArgs e)
        {
            this.shape = sender as Shapes;

            UpdateListbox(this.shape.GetBorders());
        }

        public void Render(int renderStep)
        {
            if (this.renderShape != null)
            {
                this.engine.Grafic.ShaderManager.SetShader(this.engine.Grafic.ShaderManager.ColorShader);
                this.engine.Grafic.DepthStateEnableZ(false);
                this.renderShape.DrawSubset();
                this.engine.Grafic.DepthStateEnableZ(true);
            }
        }

        #endregion Public Methods

        #region Private Methods

        private void button_Atomatic_Click(object sender, EventArgs e)
        {
            Shapes shape = Shapes.ConvertFromMesh(this.modelViewer.model.ScenerieObject.Mesh);
            this.modelViewer.model.SetShape(shape);
        }

        private void button_Delete_Click(object sender, EventArgs e)
        {
            if (listBox_Borders.SelectedIndex > -1)
            {
                for (int i = listBox_Borders.SelectedIndices.Count - 1; i >= 0; i--)
                {
                    int id = listBox_Borders.SelectedIndices[i];
                    this.shape.RemoveBorder(listBox_Borders.SelectedIndices[i]);
                    this.shape.Update();
                    listBox_Borders.SelectedIndices.Remove(listBox_Borders.SelectedIndices[i]);
                }
                UpdateListbox(this.shape.GetBorders());
                listBox_Borders_SelectedIndexChanged(null, null);
            }
        }

        private void button_Reverse_Click(object sender, EventArgs e)
        {
            if (listBox_Borders.SelectedIndex > -1)
            {
                // Get border and reverse it.
                Border border = this.shape.GetBorder(listBox_Borders.SelectedIndex);
                border.Reverse();

                // Remove border.
                this.shape.RemoveBorder(listBox_Borders.SelectedIndex);

                // Add reversed border.
                this.shape.AddBorder(border);

                UpdateListbox(this.shape.GetBorders());
            }
        }

        private void listBox_Borders_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (this.listBox_Borders.SelectedIndex >= this.shape.GetBorders().Length)
                    UpdateListbox(this.shape.GetBorders());

                if (this.listBox_Borders.SelectedIndex > -1)
                {
                    // Get border and reverse it.
                    Border[] borders = new Border[] { this.shape.GetBorder(listBox_Borders.SelectedIndex) };
                    this.renderShape.SetBorders(borders);
                    this.renderShape.Update();
                    this.renderShape.UpdateVertexBuffer(new SharpDX.Color4()
                    {
                        Alpha = 1.0f,
                        Blue = 0.0f,
                        Green = 0.0f,
                        Red = 1.0f
                    });
                }
                else
                {
                    this.renderShape.RemoveBorder(0);
                    this.renderShape.Update();
                    this.renderShape.UpdateVertexBuffer(new SharpDX.Color4()
                    {
                        Alpha = 1.0f,
                        Blue = 0.0f,
                        Green = 0.0f,
                        Red = 1.0f
                    });
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        private void UpdateListbox(Border[] borders)
        {
            this.listBox_Borders.Items.Clear();
            for (int i = 0; i < borders.Length; i++)
            {
                this.listBox_Borders.Items.Add((i + 1).ToString() + " " + borders[i].GetNumberOfPositions());
            }
        }

        #endregion Private Methods
    }
}